package com.me.screen;

import java.util.Iterator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Array;
import com.me.constant.Constant;
import com.me.control.SoundManager;
import com.me.enums.ScreenEnum;
import com.me.happybugs.HappyBugs_Main;
import com.me.helper.PreferencesData;
import com.me.object.MoveObject;

public class PlayScreen extends BaseScreen {
	TextureRegion moveObjImg;
	Array<TextureRegion> moveObjImgs;
	TextureRegion wormImg;
	Array<TextureRegion> wormImgs;
	TextureRegion backGround, blood;
	SpriteBatch batch;
	OrthographicCamera camera;
	Rectangle jumpRectangle;
	Array<MoveObject> moveObjs;
	long lastSpawTime;
	BitmapFont font;
	CharSequence sCore ="Score: 0";

	@Override
	public void show() {
		if(PreferencesData.getBoolRememberSound()){
			Constant.soundManager.playSound(SoundManager.START_GAME_SOUND);
		}
		
		font = new BitmapFont(Gdx.files.internal("SkinResourcePacker/font/arial-40-bold.fnt"),
		         Gdx.files.internal("SkinResourcePacker/font/arial-40-bold.png"), false);
		// load the images for the droplet and the bucket, 96x96 pixels each
		moveObjImgs = new Array<TextureRegion>();
		wormImgs = new Array<TextureRegion>();
		
		// Quy ước: Trong ham SpawNewObj 
		for(int i = 1; i < 9; i ++){
			moveObjImg = new TextureRegion(HappyBugs_Main.getAtlas().findRegion("datagame/ant",i));
			moveObjImgs.add(moveObjImg);
			
			wormImg = new TextureRegion(HappyBugs_Main.getAtlas().findRegion("datagame/bug",i));
			wormImgs.add(wormImg);
		}

		backGround = new TextureRegion(HappyBugs_Main.getAtlas().findRegion(
				"datagame/woodBG"));
		blood = new TextureRegion(HappyBugs_Main.getAtlas().findRegion(
				"datagame/blood"));

		// create the camera and the SpriteBatch
		camera = new OrthographicCamera();
		camera.setToOrtho(false, 1280, 720);
		batch = new SpriteBatch();

		// create a Rectangle to logically represent the bucket
		jumpRectangle = new Rectangle();
		jumpRectangle.x = -100;
		jumpRectangle.y = -100;
		
		// create the raindrops array and spawn the first raindrop
		moveObjs = new Array<MoveObject>();
		Constant.getSpeedRandom();
		stage.clear();
		stage = new Stage();
	}

	// Create new move object - Tham số iRandom để xác định vị trí random ra con vật
	private void spawnNewObj(int iRandomPos, boolean isWorm) {
		MoveObject moveObj = new MoveObject(iRandomPos, isWorm);
		moveObj.width = 96;
		moveObj.height = 96;
		switch (iRandomPos) {
		case 1:
			moveObj.x = MathUtils.random(100, 1080); // Di chuyển từ trên xuống dưới
			moveObj.y = 720;
			break;
		case 2:
			moveObj.x = MathUtils.random(100, 1080); // Di chuyển từ dưới lên trên
			moveObj.y = 0;
			break;
		case 3:
			moveObj.x = 0;
			moveObj.y = MathUtils.random(50, 600); // Di chuyển từ trái sang phải
			break;
		case 4:
			moveObj.x = 1280;
			moveObj.y = MathUtils.random(50, 600); // Di chuyển từ phải sang trái
			break;
		case 5:
			moveObj.x = MathUtils.random(0, 100); // Di chuyển chéo từ trên góc trái xuống
			moveObj.y = 720;
			break;
		case 6:
			moveObj.x = MathUtils.random(1180, 1280); // Di chuyển chéo từ trên góc phải xuống
			moveObj.y = 720;
			break;
		case 7:
			moveObj.x = 0;
			moveObj.y = MathUtils.random(0, 50); // Di chuyển chéo từ dưới góc trái lên
			break;
		case 8:
			moveObj.x = MathUtils.random(1180, 1280);
			moveObj.y = 0; // Di chuyển chéo từ dưới góc phải lên
			break;
		}
		moveObjs.add(moveObj);
	}

	int iRandomPos = 0;
	int iRandomWorm = 0;
	
	@Override
	public void render(float arg0) {

		Gdx.gl.glClearColor(0, 0, 0.2f, 1);
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

		// tell the camera to update its matrices.
		camera.update();

		// tell the SpriteBatch to render in the coordinate system specified by the camera.
		batch.setProjectionMatrix(camera.combined);

		// begin a new batch and draw the bucket and all drops
		batch.begin();
		batch.draw(backGround, 0, 0);
		font.draw(batch, sCore, 1000, 700);
		for (MoveObject objdrop : moveObjs) {
			if(objdrop.getIsWorm())
				batch.draw(wormImgs.get(objdrop.getiRand()-1), objdrop.x, objdrop.y);
			else
				batch.draw(moveObjImgs.get(objdrop.getiRand()-1), objdrop.x, objdrop.y);
		}
		batch.end();

		// Reset
		jumpRectangle.x = -100;
		jumpRectangle.y = -100;

		// process user input
		if (Gdx.input.isTouched()) {
			if(PreferencesData.getBoolRememberSound()){
				Constant.soundManager.playSound(SoundManager.TOUCH_SCREEN_SOUND);
			}
			Vector3 touchPos = new Vector3();
			touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
			camera.unproject(touchPos);
			jumpRectangle.x = touchPos.x;
			jumpRectangle.y = touchPos.y;
		}

		// check if we need to create a new raindrop
		lastSpawTime++;
		if (lastSpawTime > Constant.itimeToCreateObj) {
			iRandomPos = MathUtils.random(1, 8); //Random to choose position
			iRandomWorm = MathUtils.random(1, 4); // Random to choose worm
			if(iRandomWorm == 3)
				spawnNewObj(iRandomPos, true);
			else
				spawnNewObj(iRandomPos, false);
			lastSpawTime = 0;
		}

		// move the raindrops, remove any that are beneath the bottom edge of
		// the screen or that hit the bucket. In the later case we play back
		// a sound effect as well.
		Iterator<MoveObject> iter = moveObjs.iterator();
		while (iter.hasNext()) {
			MoveObject moveObj = iter.next();
			switch (moveObj.getiRand()){
			case 1:
				if(moveObj.getIsWorm())
					moveObj.y -=Constant.ySpeedWorm;
				else
					moveObj.y -=Constant.ySpeedMoveObj;
				if(moveObj.y + 64 < 0){
					iter.remove();
					checkEndGame(moveObj.getIsWorm());
				}
				break;
			case 2:
				if(moveObj.getIsWorm())
					moveObj.y +=Constant.ySpeedWorm;
				else
					moveObj.y +=Constant.ySpeedMoveObj;
				if(moveObj.y > 720){
					iter.remove();
					checkEndGame(moveObj.getIsWorm());
				}
				break;
			case 3:
				if(moveObj.getIsWorm())
					moveObj.x +=Constant.xSpeedWorm;
				else
					moveObj.x +=Constant.xSpeedMoveObj;
				if(moveObj.x > 1280){
					iter.remove();
					checkEndGame(moveObj.getIsWorm());
				}
				break;
			case 4:
				if(moveObj.getIsWorm())
					moveObj.x -=Constant.xSpeedWorm;
				else
					moveObj.x -=Constant.xSpeedMoveObj;
				if(moveObj.x + 64 < 0){
					iter.remove();
					checkEndGame(moveObj.getIsWorm());
				}
				break;
			case 5:
				if(moveObj.getIsWorm()){
					moveObj.x +=Constant.xSpeedWorm;
					moveObj.y -=Constant.ySpeedWorm;
				}else{
					moveObj.x +=Constant.xSpeedMoveObj;
					moveObj.y -=Constant.ySpeedMoveObj;
				}
				if(moveObj.x + 64 < 0 || moveObj.y + 64 < 0){
					iter.remove();
					checkEndGame(moveObj.getIsWorm());
				}
				break;
			case 6:
				if(moveObj.getIsWorm()){
					moveObj.x -=Constant.xSpeedWorm;
					moveObj.y -=Constant.ySpeedWorm;
				}else{
					moveObj.x -=Constant.xSpeedMoveObj;
					moveObj.y -=Constant.ySpeedMoveObj;
				}
				if(moveObj.x + 64 < 0 || moveObj.y + 64 < 0){
					iter.remove();
					checkEndGame(moveObj.getIsWorm());
				}
				break;
			case 7:
				if(moveObj.getIsWorm()){
					moveObj.x +=Constant.xSpeedWorm;
					moveObj.y +=Constant.ySpeedWorm;
				}
				else{
					moveObj.x +=Constant.xSpeedMoveObj;
					moveObj.y +=Constant.ySpeedMoveObj;
				}
				if(moveObj.x  > 1280 || moveObj.y> 720){
					iter.remove();
					checkEndGame(moveObj.getIsWorm());
				}
				break;
			case 8:
				if(moveObj.getIsWorm()){
					moveObj.x -=Constant.xSpeedWorm;
					moveObj.y += Constant.ySpeedWorm;
				}
				else{
					moveObj.x -=Constant.xSpeedMoveObj;
					moveObj.y += Constant.ySpeedMoveObj;
				}
				if(moveObj.x + 64 < 0 || moveObj.y  > 720){
					iter.remove();
					checkEndGame(moveObj.getIsWorm());
				}
				break;
			}
			
			// Neu cham trung con bo hoac con kien --> Xu ly
			if (moveObj.overlaps(jumpRectangle)) {
				if(moveObj.getIsWorm()){
					changeScreen();
				}else{
					if(PreferencesData.getBoolRememberSound()){
						Constant.soundManager.resetAllSound();
						Constant.soundManager.playSound(SoundManager.TOUCH_MOVEOBJ_SOUND);
					}
					
					batch.begin();
					batch.draw(blood, moveObj.getX(), moveObj.getY());
					batch.end();
					
					Constant.iScore ++;
					sCore = "Score: " + Constant.iScore;
					
					iter.remove();
					jumpRectangle.x = -100;
					jumpRectangle.y = -100;
					
					setMoveSpeed();
				}
			}
		}
	}

	private void changeScreen(){
		HappyBugs_Main.getApi().Vibrate();
		if(PreferencesData.getBoolRememberSound()){
			Constant.soundManager.playSound(SoundManager.END_GAME_SOUND);
		}
		stage.clear();
		HappyBugs_Main.getScreenManager().createScreen(ScreenEnum.END_GAME);
		HappyBugs_Main.getScreenManager().getScreen().show();
	}
	
	private void checkEndGame(boolean isWorm){
		if(!isWorm)
			changeScreen();
	}
	private void setMoveSpeed(){
		// Get level
		switch(Constant.iScore){
		case 7:
			Constant.LEVEL ++;
			Constant.getSpeedRandom();
			break;
		case 12:
			Constant.LEVEL ++;
			Constant.getSpeedRandom();
			break;
		case 30:
			Constant.LEVEL ++;
			Constant.getSpeedRandom();
			break;
		case 60:
			Constant.LEVEL ++;
			Constant.getSpeedRandom();
			break;
		case 100:
			Constant.LEVEL ++;
			Constant.getSpeedRandom();
			break;
		case 200:
			Constant.LEVEL ++;
			Constant.getSpeedRandom();
			break;
		case 400:
			Constant.LEVEL ++;
			Constant.getSpeedRandom();
			break;
		case 800:
			Constant.LEVEL ++;
			Constant.getSpeedRandom();
			break;
		default:
			break;
		}	
	}
	@Override
	public void dispose() {
		batch.dispose();
	}

	@Override
	public void resize(int width, int height) {
	}

	@Override
	public void pause() {
	}

	@Override
	public void resume() {
	}
}